﻿using System.ComponentModel.Design;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System;

namespace UtfprLibrary.Windows.Forms.ComponentModel {
    internal class UtfprRadioButtonActionList : UtfprActionListBase {
        private readonly UtfprRadioButtonBase linkedControl;

        public UtfprRadioButtonActionList(UtfprRadioButtonBase component, ControlDesigner designer)
            : base(component, designer) {
                linkedControl = (UtfprRadioButtonBase)LinkedControl;
                AddEventHandler(linkedControl, "SomePropertyChanged");
        }

        #region Properties

        [TypeConverterAttribute(typeof(BooleanConverter))]
        public bool IsNumeric {
            get { return (bool)GetPropertyByName("IsNumeric").GetValue(linkedControl); }
            set {
                GetPropertyByName("IsNumeric").SetValue(linkedControl, value);
                ((DesignerActionUIService)GetService(
                    typeof(DesignerActionUIService))).Refresh(linkedControl);
            }
        }

        public object Value {
            get { return GetPropertyByName("Value").GetValue(linkedControl); }
            set { GetPropertyByName("Value").SetValue(linkedControl, value); }
        }

        [DefaultValue(null)]
        [Bindable(true, BindingDirection.OneWay)]
        [TypeConverter("System.Windows.Forms.Design.DesignBindingConverter, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
        [Editor("System.Windows.Forms.Design.DesignBindingEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public object ValueField {
            get { return GetBind("ValueField"); }
            set { SetBind("ValueField", value, "ValueField"); }
        }

        #endregion

        #region Methods

        private void AddEventHandler(object target, string methodName) {
            var eInfo = target.GetType().GetEvent("PropertyChanged");
            var handler = Delegate.CreateDelegate(
                eInfo.EventHandlerType, this, methodName);
            eInfo.AddEventHandler(target, handler);
        }

        private void SomePropertyChanged(object sender, PropertyChangedEventArgs e) {
            if (e.PropertyName == "Value") {
                if (VeriryIsNumeric(sender)) {
                    ValidateProperty(sender);
                }
            } else if (e.PropertyName == "IsNumeric") {
                if (VeriryIsNumeric(sender)) {
                    try {
                        ValidateProperty(sender);
                    } catch (FormatException) {
                        SetText(sender, "1");
                    }
                } else if (!VeriryIsNumeric(sender)) {
                    SetText(sender, "Insira um valor");
                }
            }
        }

        private void ValidateProperty(object sender) {
            try {
                int.Parse(GetText(sender));
            } catch (FormatException) {
                throw new FormatException("Valor inválido, somente valores numéricos são aceitos");
            }
        }

        private bool VeriryIsNumeric(object sender) {
            return (bool)sender.GetType()
                .GetProperty("IsNumeric").GetValue(sender, null);
        }

        private string GetText(object sender) {
            return (string)sender.GetType()
                .GetProperty("Value").GetValue(sender, null);
        }

        private void SetText(object sender, string message) {
            sender.GetType().GetProperty("Value")
                .SetValue(sender, message, null);
        }

        #endregion

        #region Override

        public override DesignerActionItemCollection GetSortedActionItems() {
            var items = new DesignerActionItemCollection();
            
            items.Add(new DesignerActionHeaderItem("Dados"));

            items.Add(new DesignerActionPropertyItem(
                "IsNumeric", "IsNumeric", "Dados", "Escolha o tipo de valor a ser salvo no banco."));

            items.Add(new DesignerActionPropertyItem(
                "Value", "Value", "Dados", "O valor a ser salvo no banco."));

            items.Add(new DesignerActionPropertyItem(
                "ValueField", "ValueField", "Dados", "Escolha o campo a ser salvo."));

            return items;
        }

        #endregion
    }
}
